#include "Goblin.hh"
#include <random>

Goblin::Goblin()
     : Character("Goblin", 
        "In the blackened heart of 13th-century Bavarian mines, orphaned children were forced to dig for God's Tears—cursed amber containing prehistoric parasites. Those who rebelled were sealed alive in sulfur pits with rotten church wafers stuffed down their throats. Over decades, the Communion mold fused with parasitic larvae in their guts, birthing warped hybrids that gnawed through granite to escape. Their twisted prayers became the first Klikker tongue—a guttural language that drives listeners to chew their own fingers."
        "The Goblin is a tumorous mass of petrified children fused at the spine, dragging a calcified altar-chalice overflowing with molten amber. Its six-jawed mouth spews hallucinogenic spores that rot wood into edible flesh. Victims begin compulsively swallowing stones, their bellies swelling with geode 'eggs' that hatch metallic centipedes. Destroying its chalice triggers a chain reaction—every ingested stone in nearby hosts explodes into glass shrapnel, while the King reforms from the resulting blood-puddles, now studded with victims' crystallized screams.",
        100, 25, 10),
                  critProbability(0.2f),  // 20% critical hit probability
                  critMultiplier(2.0f) {   // Double damage
}

Goblin::~Goblin() {}
// Attack method, return whether the attack was successful
Goblin::Goblin(const Goblin& other) : Character(other), critProbability(other.critProbability), critMultiplier(other.critMultiplier) {
    // Copy constructor logic if needed
}
Goblin& Goblin::operator=(const Goblin& other) {
    if (this != &other) {
        Character::operator=(other); // Call the assignment operator of the base class
        critProbability = other.critProbability;
        critMultiplier = other.critMultiplier;
    }
    return *this;
}
bool Goblin::attack(ICharacter& target) {
    static std::random_device rd;
    static std::mt19937 gen(rd());
    std::uniform_real_distribution<> dis(0.0, 1.0);

    // Calculate the basic damage
    unsigned baseDamage = getAttack();
    
    // Determine whether it is a critical hit
    if(dis(gen) < critProbability) {
        baseDamage = static_cast<unsigned>(baseDamage * critMultiplier);
    }
    
    // Call the takeDamage method of the target
    return target.takeDamage(baseDamage);
}